import java.io.FileWriter;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.SimpleDateFormat;

import org.freeswitch.*;
import org.freeswitch.swig.*;


public class Optimized implements FreeswitchScript, DTMFCallback, HangupHook{
	
	Common ob=null;
	String arg="";
	JavaSession session=null;
	Connection con =null;
	ResultSet set=null;
	String script_name="lua_in_java";  
	String phonenum="";
	String role="";
	String Ending="";
	String input="";
	String aosd="";
	String start="";
	long sessid;
	String digits="";
	String rep="N";
	int GlobalCnt=0;
	public Optimized()
	{
		
	}

	
	//User Defined Functions

	
	
	public void validate_caller() throws Exception
	{
		session.execute("set_audio_level", "write 1");
		while(session.ready()==true)
		{
			Statement update_query=con.createStatement();
			
			update_query.executeUpdate("update I_Caller set question = 'N' where Phone_no = 1003");
			
			Statement select_query=con.createStatement();
			//freeswitch.consoleLog("info", arg1);
			set=select_query.executeQuery("select * from I_Caller where Phone_no = '" +phonenum+"'");
			
			if(set.getString(1)!=null && set.getString(2)=="N")
			{
				role="guest";
			}
			
			if(set.getString(1)==null || set.getString(2)==null)
			{
			
				role="guest";
				Statement insert_query=con.createStatement();
				insert_query.executeUpdate("insert into I_Caller(Phone_no,question) values ('"+phonenum+ "','N')");
				
			}
			
			if(set.getString(1)!=null && set.getString(2)=="Y")
			{
				role="aspirant";
			}
			
			//freeswitch.consoleLog("info",)
			set=select_query.executeQuery("select * from Responder where responder_no = '" +phonenum+"'");
			if(set.getString(1)!=null && set.getString(2)==null)
			{
				role="guest";
			}
			else
			{
				role="responder";
			}
			
		}
	}
	
	public void respoder_menu() throws Exception
	{
		session.answer();
		session.setAutoHangup(false);
		ob.read(aosd+"/prompts/welcome.wav",200);
		ob.read(aosd+"/prompts/option.wav",200);
		Statement select_query=con.createStatement();
		set=select_query.executeQuery("SELECT * FROM R_ques_ans WHERE responder_ans is NULL");
		String x=null;
		//set.last();
		//int row_number=set.getRow();
		if(set.getString(1)==null)
		{
			ob.read(aosd+"/prompts/noQ.wav",200);
			
		}
		else
		{
			while(set.next())
			{
				freeswitch.consoleLog("info", script_name +" : SQL answer is = "+set.getString(1)+"\n");
				String dir_Q=ob.sd+"/Q/"+set.getString(2)+"";
				//Check wether z is declared globally or locally
				String z=playfile(dir_Q);
				if(z=="2")
				{
					//no use of statement
				}
				else
				{
					if(z=="9")
					{
						break;
					}
				}
			}
		}
	}
	
	public void guest_menu(int index) throws Exception
	{
		session.answer();
		session.setAutoHangup(false);
		
		String welcome = aosd+"/menu/0.wav";
		
		ob.read(welcome,200);
		ob.read(aosd+"/prompts/details.wav",100);
		ob.read(aosd+"/prompts/disclaimer.wav",100);
		while(session.ready()==true)
		{
			Ending="N";
			String flag="*";
			flag =Nodes(index);
			if(flag == "*")
			{
				continue;
				
			}
			else
			{
				if(flag=="0")
				{
					input="";
					ob.read(aosd+"/prompts/back_main.wav",0);
				}
				
				else
				{
					if(flag=="8")
					{
						//freeswitch.consoleLog("info", script_name .. " : input was ++++++  = " .. input .. "\n");
						int j=input.length();
						//freeswitch.consoleLog("info", script_name .. " : length of the input is  = " .. j .. "\n");
						input=input.substring(0, j-1);
						
					}
					else
					{
						if(flag=="9")
						{
							break;
						}
						else
						{
							if(flag==null)
							{
								flag="";
								//freeswitch.consoleLog("info", script_name .. " : adding to input ------ " .. tostring(flag) .. 	"\n");
								input= input+flag;
							}
							else
							{
								//freeswitch.consoleLog("info", script_name .. " : adding to input ------ " .. tostring(flag) .. 	"\n");
								input=input+flag;
								Statement update_query=con.createStatement();
								update_query.executeUpdate("update HitCount set Count= Count +1 where level_id = '" +input +"'");
								
							
							}
							flag ="*";
						}
					}
				}
			}
		}
	}
	
	public String Nodes(int index) throws Exception
	{
		String key="";
		digits="";
		PrintWriter inputStream =new PrintWriter (new FileWriter(ob.logfilename));
		
	
		
		Statement select_query=con.createStatement();
		if(input=="")

		{
			GlobalCnt=GlobalCnt+1;
			if(GlobalCnt==10)
			{
				ob.hangup();	
			}
		}
		
		if(index==1)
		{
			set=select_query.executeQuery("SELECT * FROM Nodes WHERE level_id like '"+ input + "_' and level_id != 42 order by level_id");
		}
		else
			set=select_query.executeQuery("SELECT * FROM Nodes WHERE level_id like '"+ input + "_' order by level_id");
//		freeswitch.consoleLog(arg0, arg1);
		int i=1;
		if(set.getString(1)==null)
		{
			ob.read(aosd+"/prompts/invalid_option.wav",200);
			int j=input.length();		
			
			 
			inputStream.write(sessid+ "\t" + session.getVariable("caller_id_number")+ "\t" + session.getVariable("destination_number")+ "\t" + ob.ostime()+"\t"+ "Invalid Option at Node id"+ "\t"+ input+"\n");  
			input=input.substring(0,j-1);
			return "*";
		}
		
		
		while(set.next())
		{
			if(set.getString(1)== input+"*")
			{
				String flag1=checkfunc(set.getString(1),set.getString(2),set.getString(3));
				if(flag1=="0" && Ending=="N")
				{
	//				freeswitch.consoleLog
					while(true)
					{
						String Filename= aosd+"/menu/"+set.getString(2);
						ob.read(Filename,200);
						ob.read(aosd+"/prompts/repeat_response.wav",2000);
						String f=ob.use();
						if(f=="5")
						{
							
						}
						else
							return "0";
					}
				}
				else
				{
					return flag1;
				}
					
				
			}
			else
			{
				String Filename=aosd+ "/menu/"+ set.getString(2);
				//freeswitch.consoleLog();
			    ob.read(Filename,0);
			    ob.read(aosd+"/Digits/"+i+".wav",1500);
			    key=ob.use();
//			    freeswitch.consolelog();
			    if(key!="")
			    {
				   i=i+1;
				   rep="N";
				   return key;
			     }
			     else
			     {
				    i=1+1;
				    rep="Y";
			     }
		      }
		}
		if(rep=="Y")
		{
			ob.read(aosd+"/prompts/no_option.wav",100);
			return "*";
		}
		return digits;//no reason to have thsi but to resolve error
	}
	
	
	public String checkfunc(String id,String func,String Tag) throws Exception
	{
		String key="";
		if(func=="get_result()")
		{
			key=get_result();
			Ending="Y";
			return key;
			
		}
		
		if(func=="get_faq()")
		{
			key=get_faq();
			Ending="Y";
			return key;
		}
		
		if(func=="record_my_question")
		{
			key=record_my_question(null);
			Ending="Y";
			return key;
			
		}
		if(func=="play_my_response()")
		{
			key=play_my_response();
			Ending="Y";
			return key;
		}
		else
		{
			Ending="N";
			return ("0");
		}
	}
	
	public void speak(String message,String method)
	{
		session.execute("set_audio_level","write 4");
		session.say(message, "en", "number", method,"");
		session.execute("set_audio_level","write 0");
	}
	
	public String get_result()throws Exception
	{
		String app_no="";
		boolean cont=false;
		while(true)
		{
			session.flushDigits();
			//some more arguments in this function needed
			app_no=session.read(9,9,aosd+"/prompts/9digit.wav", 4000, "#",0);
			session.flushDigits();
			freeswitch.consoleLog("info", script_name+" app_no is "+app_no);
			int len=app_no.length();
			if(len==9)
			{
				session.read(0, 0,aosd+"/prompts/You_have_entered.wav",200,"#",0);
				speak(app_no,"iterated");
				while(true)
				{
					ob.read(aosd+"/prompt/confirmation.wav",5000);
					String key=ob.use();
					if(key=="1")
					{
						cont=false;
						Statement select_query=con.createStatement();
						set=select_query.executeQuery("select * from Results where App_no='"+app_no+"'");
						if(set.getString(4)!="0")
						{
							ob.read(aosd+"/prompts/Result.wav",100);
							speak(set.getString(1),"iterated");
							session.read(0,0, aosd+"/prompts/congratulation.wav", 200,"#",0);
							session.read(0,0, aosd+"/prompts/Overall.wav", 200,"#",0);
							speak(set.getString(4),"pronounced");
							session.read(0, 0, "", 100, "#",0);
							if(set.getString(5)!="0")
							{
								session.read(0, 0, aosd+"/prompts/Catagory.wav", 200,"#",0);
								freeswitch.consoleLog("info","Got row[5] :"+set.getString(5)+'\n');
								String msg=set.getString(5);
								speak(msg,"pronounced");
								session.read(0,0,"",100,"#",0);
								
							}
							break;
						}
						else
						{
							session.read(0,0,aosd+"/prompts/sorry.wav",200,"#",0);
							break;
						}
					}
					else
					{
						cont =true;
						if(key==null || key=="")
						{
							
						}
						else
						{
							break;
						}
					}
					if(session.ready()==false)
					{
						freeswitch.consoleLog("info", script_name+"Message from playfile>>>2 >>> User Disconnected");
						try {
							ob.hangup();
						} catch (Exception e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
						break;
					}
				}
				
				if(cont==false)
				{
					break;
				}
			}
			if(session.ready()==false)
			{
				freeswitch.consoleLog("info", script_name+"Message from playfile>>>2 >>> User Disconnected");
				try {
					ob.hangup();
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				break;
			}
		}
		session.read(0,0,aosd+"/prompts/Result_avl.wav",200,"#",0);
		return "0";
	}

	public String get_faq() throws Exception
	{
		int no_faq=3;
		for(int i=0;i<=no_faq;i++)
		{
			while(true)
			{
//				freeswitch.consoleLog	
				ob.read(aosd+"/Q/Q"+ i + ".wav",2000);
				String j=ob.use();
				if(j=="")
				{
					while(true)
					{
//						freeswitch.consoleLog
						ob.read(aosd+"/prompts/response.wav",200);
						ob.read(aosd+"/A/A"+i+".wav",2000);
						String h=ob.use();
						if(h=="5")
						{
							
						}
						else
						{
							if(h=="0" || h=="9" || h=="8")
							{
								return h;
							}
							else 
								break;
						}
					}
					if(i<no_faq)
					{
						ob.read(aosd+"/prompts/nextQ.wav",500);
					}
					break;
					
				}
				else
				{
					if(j=="5")
					{
						
					}
					else
					{
						if(j=="0" || j=="9" || j=="8")
							return j;
						else
						{
							ob.read(aosd+"/prompotd/nextQ.wav",500);
							break;
						}
						
					}
				}
			}
		}
		Ending="Y";
		return "0";
	}
	
	public String playfile(String file_name) throws Exception
	{
		//dont know where this arg[1] has come
		
		arg=file_name;
		freeswitch.consoleLog("info", script_name+"playing"+file_name+"\n");
		if(start=="N")
		{
			ob.read(aosd+"/prompts/nextQ.wav",200);
			
		}
		ob.read(file_name,100);
		String x=null;
		if(role=="responder")
		{
			ob.read(aosd+"/prompts/record_response.wav",0);
			ob.read(aosd+"/Digits/2.wav",100);
			ob.read(aosd+"/prompts/for_next_Q.wav",0);
			ob.read(aosd+"/Digits/6.wav",2000);
		}
		
		else
		{
			ob.read(aosd+"/prompts/blank.wav",2000);
		}
		
		x=ob.use();
		if(session.ready()==false)
		{
			freeswitch.consoleLog("info", script_name+"Message from playfile>>>2 >>> User Disconnected");
			ob.hangup();
			
		}
		
		return x;
	}
	
	public String record_my_question(String Qid) throws Exception
	{
		PrintWriter inputStream=new PrintWriter(new FileWriter(ob.logfilename));	//overwrite whatever has been written in above functions(problem :()
		//SimpleDateFormat sessid1=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		//sessid1.setTimeZone(TimeZone.getTimeZone("UTC"));
		//String Time=sessid.format(new Date()); 
		String partfilename= ob.ostime()+".mp3";
		String filename;
		if(role=="guest" || role=="aspirant")		
		{
			filename=ob.sd+"/Q/"+partfilename;
		}
		else
			filename=ob.sd+"/A"+partfilename;
		int maxlength=60000;
		String d;
		do{
			d=ob.use();
			if(d==ob.GLOBAL_MENU_MAINMENU)	//can't even find this GLOBAL_MAIN_MAINMENU 
				return d;
			session.execute("playback", "tone_stream://%(500,0,620)");
//			freeswitch.consoleLog()
			inputStream.write(sessid+"\t"+session.getVariable("caller_id_number")+ "\t" + session.getVariable("destination_number")+ "\t"+ob.ostime()+"\t"+"Record"+"\t" +filename+"\n");//might be some problem with this time 
			session.execute("record",filename+" "+ maxlength+" 100 5");
			d=ob.use();
			if(session.ready()==false)
			{
		//		freeswitch.consoleLog();
				ob.hangup();
				break;
			}
			if(d==ob.GLOBAL_MENU_MAINMENU)
			{
//				Has to Delete File
				return d;
			}
			int review_cnt=0;
			while(d!= ob.GLOBAL_MENU_MAINMENU && d!="1" && d!="2" && d!="3")
			{
				ob.read(aosd+"/prompts/recording_check.wav",1000);
				ob.read(filename,1000);
				ob.read(aosd+"/prompts/not_satisfied.wav",2000);
				ob.sleep(6000);		//Not defined this function
				d=ob.use();
				if(session.ready()==false)
				{
//					freeswitch.consoleLog();					
					ob.hangup();
				}
			}
			if(d!="1" && d!="2")
			{
//				Has to delete file
				if(d==ob.GLOBAL_MENU_MAINMENU)
					return d;
				else if(d=="3")
				{
					ob.read(aosd+"/prompts/message_cancel.wav",500);
					Ending="Y";
					return "0";
				}
			}
			if(session.ready()==false)
			{
//				freeswitch.consoleLog()
				ob.hangup();
				int done=1;			// Can't find where u have defined done
				break;
			}
		}while(d=="5");
		if(session.ready()==true && role=="responder")
		{
			Statement update_query=con.createStatement();
			update_query.executeUpdate("update R_ques_ans set responder_ans='" + partfilename + "' where user_id = " + Qid + "");
			ob.read(aosd+"/prompts/response_back.wav",100);
			update_query.executeUpdate("insert into Replies (reply_text) values ('" + partfilename + "')");
			update_query.executeUpdate("update Mapping set reply_id = (select reply_id from Replies where reply_text = '"+ partfilename +"') where question_id = (select question_id from Questions where question_text= (select caller_ques from R_ques_ans where responder_ans='"+ partfilename +"') ) and reply_id is NULL");
			set=update_query.executeQuery("select Phone_no from R_ques_ans where responder_ans = '" + partfilename +"'");
//			freeswitch.consoleLog();
			if(set.getString(1)!=null)
				send_sms("Your query has been resolved.Please Dial 09013182123 or 011-25099209 to listen the rrsponse. --Sent by Winter School 2011, IIIT Delhi",set.getString(1));
			Ending="N";
			return "0";

			
			
		}
//		DataBase Updation for new User
		if(session.ready()==true && (role == "aspirant" || role=="guest"))
		{
			Statement update_query=con.createStatement();
			update_query.executeUpdate("insert into R_ques_ans (caller_ques, Phone_no) values('" + partfilename + "','" + phonenum + "')");
			update_query.executeUpdate("insert into Mapping values((select question_id from Questions where question_text='" + partfilename + "'),NULL)");
			update_query.executeUpdate("update I_Caller set question='Y' where Phone_no='" + phonenum + "'");
			set=update_query.executeQuery("select responder_no from Responder");
//			freeswitch.consoleLog();
			while(set.next())
			{
				send_sms(" A new query has arrived for you. Dial 09013182123 to answer the query --Sent By Winter School 2011, IIIT Delhi",set.getString(1));
			}
			Ending="N";
			return "0";
		}
		return d;
	}
	
	
	public void send_sms(String message,String number) throws Exception
	{
		int num_len=number.length();
		if(num_len>6)
		{
			Statement update_query=con.createStatement();
			//query to check again
			update_query.executeUpdate("insert into sms_sent(request_time,phone,message,sent_time,sent) values(now(),'"+number+"','"+message+"',NULL,'n')");
			freeswitch.consoleLog("info", ":SQL Querry="+"insert into sms_sent(request_time,phone,message,sent_time,sent) values(now(),'"+number+"','"+message+"',NULL,'n')\n");
			
		}
	}
	
	public String play_my_response()throws Exception
	{
		java.sql.Statement query3=con.createStatement();
//		freeswitch.console_log("info", );
		String key="";
		
		set=query3.executeQuery("select responder_ans from R_ques-ans where Phone no = '" + phonenum + "' and responder_ans is not NULL ");
		if(set.getString(1)==null)
			ob.read(aosd+"/prompts/noresponse.wav",200);
		else
		{
			ob.read(aosd+"/prompts/exitmain.wav",200);
			while(set.next())
			{
				ob.read(aosd+"/prompts/response.wav",200);
				String dir=ob.sd+"/A"+set.getString(1);		//could not find sd anywhere in the file
				while(true)
				{
					ob.read(dir,500);
					ob.read(aosd+"/prompts/repeat_response.wav",3000);
					String f=ob.use();
					if(f=="5")
					{
						
					}
					else
					{
						if(key=="9" || key=="0" || key=="8")
						{
							Ending="Y";
							return key;
						}
						break;
					}
				}
			}
		}
		return "0";
	}
	
	public void select_voice()
	{
		int k=2;
		freeswitch.consoleLog("info", script_name+":User Selected voice Number:"+k+"\n");
		if(k==1)
		{
			aosd=ob.basedir+"/scripts/IIITD/sounds/anjali";
			freeswitch.consoleLog("info", script_name +" : Voice Selected Anjali \n");
		}
		else
		{
			if(k==2)
			{
				aosd=ob.basedir+"/scripts/IIITD/sounds/niharika";
				freeswitch.consoleLog("info", script_name +" : Voice Selected niharika \n");
			}
			else
			{
				if(k==3)
				{
					aosd=ob.basedir+"/scripts/IIITD/sounds/Ramjot";
					freeswitch.consoleLog("info", script_name +" : Voice Selected Ramjot \n");
				}
				else
				{
					aosd=ob.basedir+"/scripts/IIITD/sounds/anjali";
					freeswitch.consoleLog("info", script_name +" : Didn't Selected any voice. Hence anjali \n");
				}
			}
		}
	}
	//*********************
	@Override
	public void run(String arg0, String arg1) {
		try {
		
		ob=new Common(this);
		sessid=ob.ostime();
		aosd=ob.basedir+"//scripts//IIITD//sounds//niharika";
			con=DriverManager.getConnection("jdbc:mysql://localhost/ivr", "ivr", "ivr");
		
		
		session.answer();
		session.setVariable("playback_terminators","#");
		session.setHangupHook(this);
		session.setDTMFCallback(this, "arg");
		//session.
		
			validate_caller();
		
		//freeswitch.consolelog()
		session.setVariable("phonenum", phonenum);
		// generate a menu
		
		session.set_tts_parms("flite","rms");
		
		while(session.ready()==true)
		{
			ob.read(ob.basedir+"//scripts//IIITD//sounds//tune.wav", 100);
			if(role=="responder")
			{
				respoder_menu();
				
			}
			if(role=="guest")
			{
				guest_menu(1);
				
			}
			
			if(role=="aspirant")
			{
				guest_menu(2);
			}
			
			ob.read(aosd+"//prompts//thanks.wav", 200);
			break;
		}
		
		session.hangup("bye");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@Override
	public String onDTMF(Object arg0, int arg1, String arg2) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onHangup() {
		// TODO Auto-generated method stub
		
	}

}
